package java高并发核心编程.多线程.交替打印;

import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

//Lock+Condition
public class Demo4 {
    private static AtomicInteger count = new AtomicInteger();
    private static Lock lock = new ReentrantLock();
    private static Condition odd = lock.newCondition();
    private static Condition even = lock.newCondition();
    private static boolean flag = false; //标志变量，初始值为false,代表奇数线程先打印
    private static final int MAX = 100;

    //奇数线程
    static class OddThread implements Runnable {
        @Override
        public void run() {
            while (count.get() < MAX) {
                lock.lock();
                try {
                    while (flag) {
                        try {
                            odd.await();
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }
                    System.out.println(Thread.currentThread().getName() + "-->" + count.getAndIncrement());
                    flag = true;     //切换标志变量
                    even.signal();//唤醒偶数线程继续打印
                } catch (RuntimeException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
        }
    }

    //偶数线程
    static class EvenThread implements Runnable {

        @Override
        public void run() {
            while (count.get() <= MAX) {
                lock.lock();
                try {
                    while (!flag) {
                        even.await();
                    }
                    System.out.println(Thread.currentThread().getName() + "-->" + count.getAndIncrement());
                    flag = false; //切换标志变量
                    odd.signal();//唤醒奇数线程继续打印
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
        }
    }

    public static void main(String[] args) {
        Thread odd = new Thread(new OddThread(), "奇数线程");
        Thread even = new Thread(new EvenThread(), "偶数线程");
        odd.start();
        even.start();
    }

}
